package dynamic;

public class CompareGene {
    //初始化两个基因序列
    private String gene1;
    private String gene2;
    //分值矩阵
    private int[][] arrayCourse;
    //变更后的基因序列
    private String geneResult1;
    private String geneResult2;

    //构造函数
    public CompareGene(String gene1, String gene2) {
        this.gene1 = gene1;
        this.gene2 = gene2;
        initArrayCourse();
        loadDNA();
    }

    //初始化arrayCourse基因序列,比较2个基因序列
    private void initArrayCourse() {
        arrayCourse = new int[gene1.length() + 1][gene2.length() + 1];

        //初始化第一列的值（gene1）（前一个基因数与_比较的结果加上前一个数值等于后一个数值）
        for (int i = 0; i < arrayCourse.length - 1; i++)
            arrayCourse[i + 1][0] = arrayCourse[i][0] + getCourse(gene1.charAt(i), '_');

        //初始化第一行的值（gene2）（前一个基因数与_比较的结果加上前一个数值等于后一个数值）
        for (int i = 0; i < arrayCourse[0].length - 1; i++)
            arrayCourse[0][i + 1] = arrayCourse[0][i] + getCourse('_', gene2.charAt(i));

        for (int i = 0; i < arrayCourse.length - 1; i++) {
            for (int j = 0; j < arrayCourse[0].length - 1; j++) {
                int v1, v2, v3;
                //情况1：gene1和'_'搭配 + gene2的结果
                v1 = arrayCourse[i][j + 1] + getCourse(gene1.charAt(i), '_');

                //情况2：gene1和gene2搭配 + 前一次的结果
                v2 = arrayCourse[i][j] + getCourse(gene1.charAt(i), gene2.charAt(j));

                //情况3：'_'和gene2搭配 +
                v3 = arrayCourse[i + 1][j] + getCourse('_', gene2.charAt(j));

                //选出匹配值最大的数值放在 + gene1的结果
                arrayCourse[i + 1][j + 1] = getMaxNum(v1, v2, v3);
            }
        }
    }

    public static int getIndex(char gene) {
        int index = 0;
        switch (gene) {
            case 'A':
                break;
            case 'C':
                index = 1;
                break;
            case 'G':
                index = 2;
                break;
            case 'T':
                index = 3;
                break;
            case '_':
                index = 4;
                break;
        }
        return index;
    }

    //基因序列分值矩阵对应的值
    public static int getCourse(char gene1, char gene2) {
        int gene1Index = getIndex(gene1);
        int gene2Index = getIndex(gene2);
        int[][] arr = {
                {5, -1, -2, -1, -3},
                {-1, 5, -3, -2, -4},
                {-2, -3, 5, -2, -2},
                {-1, -2, -2, 5, -1},
                {-3, -4, -2, -1, 0}
        };
        return arr[gene1Index][gene2Index];
    }

    //判断该字符串是否是正确的基因序列（仅由ATGC组成）
    public static boolean checkLetter(String str) {
        String geneCode = "ATGC";
        for (int i = 0; i < geneCode.length(); i++) {
            str = str.replaceAll(geneCode.charAt(i) + "", "");
        }
        return str.trim().equals("");
    }

    //获取变更后的gene1和gene2
    private void loadDNA() {
        geneResult1 = "";
        geneResult2 = "";
        int row = gene1.length();//行gene1的长度
        int column = gene2.length();//列gene2的长度
        while (row != 0 || column != 0) {
            if (row == 0)//当行等于0时，geneResult1已经匹配完成，geneResult2前面的剩余基因与空格匹配
            {
                for (int i = 0; i < column; i++)
                    geneResult1 = "_" + geneResult1;//匹配后的geneResult1
                geneResult2 = gene2.substring(0, column) + geneResult2;//匹配后的geneResult2
            }
            if (column == 0)//列为geneResult2 同行一样
            {
                for (int i = 0; i < row; i++)
                    geneResult2 = "_" + geneResult2;
                geneResult1 = gene1.substring(0, row) + geneResult1;
            }
            if (row == 0 || column == 0)
                return;

            //gene1的最后一个基因和空格匹配
            int top = arrayCourse[row - 1][column] + getCourse(gene1.charAt(row - 1), '_');
            //gene2的最后一个基因和空格匹配
            int left = arrayCourse[row][column - 1] + getCourse(gene2.charAt(column - 1), '_');
            //gene1的最后一个基因和gene2最后一个基因匹配
            int both = arrayCourse[row - 1][column - 1] + getCourse(gene1.charAt(row - 1), gene2.charAt(column - 1));
            int value = arrayCourse[row][column];
            if (value == top) {
                geneResult1 = gene1.charAt(row - 1) + geneResult1;
                geneResult2 = "_" + geneResult2;
                row--;
            } else if (value == left) {
                geneResult1 = "_" + geneResult1;
                geneResult2 = gene2.charAt(column - 1) + geneResult2;
                column--;
            } else {
                geneResult1 = gene1.charAt(row - 1) + geneResult1;
                geneResult2 = gene2.charAt(column - 1) + geneResult2;
                row--;
                column--;
            }
        }
    }

    public int getResult() {
        return arrayCourse[gene1.length()][gene2.length()];
    }

    //获取3个数中的最大项
    private int getMaxNum(int a, int b, int c) {
        int max = a;
        max = b > max ? b : max;
        max = c > max ? c : max;
        return max;
    }

    public String getGeneResult1() {
        return geneResult1;
    }

    public void setGeneResult1(String geneResult1) {
        this.geneResult1 = geneResult1;
    }

    public String getGeneResult2() {
        return geneResult2;
    }

    public void setGeneResult2(String geneResult2) {
        this.geneResult2 = geneResult2;
    }
}
